package com.wave.gate.netty;

import com.alibaba.fastjson2.JSON;
import com.wave.gate.dto.FaceMessage;
import com.wave.gate.enums.RedisKeyEnum;
import com.wave.gate.util.GuavaCache;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

import static com.wave.gate.util.GuavaCache.AI_CACHE;
import static com.wave.gate.util.GuavaCache.AI_WX_CACHE;

@Slf4j
public class FaceDecoder extends ByteToMessageDecoder {
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> list) throws Exception {
        //0	      1	      2	         3	            4	          5.6.7...n	    n+1
        //起始位	流水号	命令值	数据长度(高位)	数据长度(低位)	数据内容（json）	检验位
        //0xFA	0x01	0x00	0x03	        0x00	        0x00 0x00 0x00	0xFF
        // 检查ByteBuf数据是否完整
        if (in.readableBytes() < 5) {
            return;
        }

        // 标记ByteBuf读取索引位置
        in.markReaderIndex();

        // 读取数据包长度
        byte[] header = new byte[5];
        in.readBytes(header);
        StringBuilder sb = new StringBuilder();
        sb.append("faceDecoder（").append(ctx.channel().remoteAddress()).append("）,起始位到数据长度位:")
                .append(bytesToHexString(header));
        int length = (header[3] & 0xFF) << 2 | (header[4] & 0xFF);
        sb.append(",数据内容长度:").append(length);

        // 如果ByteBuf中可读字节数不足一个数据包长度，则将读取索引位置恢复到标记位置，等待下一次读取
        if (in.readableBytes() < length) {
            in.resetReaderIndex();
            return;
        }
        // 读取数据
        byte[] content = new byte[length];
        in.readBytes(content);
        sb.append(",数据内容:\n").append(new String(content));
        sb.append(",校验位:");
        sb.append(in.readByte());
        log.info(sb.toString());
        FaceMessage faceMessage = JSON.parseObject(content, FaceMessage.class);
        //如果缓存中存在，就不需要进行通行了
        if(GuavaCache.FACE_CACHE.getIfPresent(faceMessage.getEmpNo() + faceMessage.getDeviceType())!=null){
            log.info("重复扫脸,重复扫脸,重复扫脸!!!");
            return;
        }
        String AI = AI_WX_CACHE.getIfPresent(RedisKeyEnum.KEY_AI_ALARM.getCode());
        if(StringUtils.isNotEmpty(AI) && "危险区域闯入".equals(AI)){
            log.info("通道内有人，通道内有人，通道内有人，禁止扫脸!!!");
            return;
        }
        list.add(faceMessage);
    }

    public static String bytesToHexString(byte[] b) {
        StringBuilder sbu = new StringBuilder();
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sbu.append(hex.toUpperCase());
        }
        return sbu.toString();
    }
}
